/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.alxbrendmaquinarias.controller.operation;

import com.alxbrendmaquinarias.model.AccountForPay;
import com.alxbrendmaquinarias.model.Company;
import com.alxbrendmaquinarias.model.DetailInputDocument;
import com.alxbrendmaquinarias.model.Employee;
import com.alxbrendmaquinarias.model.InputDocument;
import com.alxbrendmaquinarias.model.Product;
import com.alxbrendmaquinarias.model.ProductShop;
import com.alxbrendmaquinarias.model.Provider;
import com.alxbrendmaquinarias.model.Shop;
import com.alxbrendmaquinarias.model.Storehouse;
import com.alxbrendmaquinarias.model.StorehouseProduct;
import com.alxbrendmaquinarias.service.AccountForPayService;
import com.alxbrendmaquinarias.service.CompanyService;
import com.alxbrendmaquinarias.service.InputDocumentService;
import com.alxbrendmaquinarias.service.ProductShopService;
import com.alxbrendmaquinarias.service.ProviderService;
import com.alxbrendmaquinarias.service.ShopService;
import com.alxbrendmaquinarias.service.StorehouseProductService;
import com.alxbrendmaquinarias.service.StorehouseService;
import com.alxbrendmaquinarias.util.VarUtil;
import com.alxbrendmaquinarias.util.faces.FacesUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import org.omnifaces.util.Faces;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 *
 * @author Max
 */
@Controller
public class InputProductController implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @Autowired
    StorehouseService storehouseService;
    @Autowired
    CompanyService companyService;
    @Autowired
    ShopService shopService;
    @Autowired
    ProductShopService productShopService;
    @Autowired
    StorehouseProductService storehouseProductService;
    @Autowired
    AccountForPayService accountForPayService;

    private Integer firstWizard;
    private Integer secondWizard;

    private List<Storehouse> listStorehouse;
    private Storehouse storehouse = new Storehouse();
    private List<Shop> listShop;
    private Shop shop = new Shop();
    //////////////////////////////////
    private List<Company> listCompany;
    private Company company = new Company();
    private AccountForPay accountForPay;
    //////////////////////////////////////
    private LazyDataModel<ProductShop> lazyModelProductShop;
    private LazyDataModel<StorehouseProduct> lazyModelStorehouseProduct;
    private StorehouseProduct storehouseProduct = new StorehouseProduct();
    /////////////////////////////////////
    private ProductShop productShop = new ProductShop();
    private String searchForCode = "";
    private String searchForName = "";
    private String namedQuery = "ProductShop.findAll";
    private String namedQueryStorehouseProduct = "StorehouseProduct.findAll";
    private Map<String, Object> parameters = null;
    private Map<String, Object> mapParam = null;

    public LazyDataModel<StorehouseProduct> getLazyModelStorehouseProduct() throws Exception {
        if (lazyModelStorehouseProduct == null) {
            lazyModelStorehouseProduct = new LazyDataModel<StorehouseProduct>() {
                @Override
                public List<StorehouseProduct> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                    //return super.load(first, pageSize, sortField, sortOrder, filters); //To change body of generated methods, choose Tools | Templates.

                    List<StorehouseProduct> lazyPS;
                    try {
                        lazyPS = productShopService.listLazy(namedQueryStorehouseProduct, getParameters(), first, pageSize);
                        System.out.println("Laz: " + lazyPS);
                    } catch (Exception ex) {
                        lazyPS = new ArrayList<>();
                        //Logger.getLogger(InputProductController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return lazyPS;
                }
            };
            lazyModelStorehouseProduct.setRowCount(storehouseProductService.count("StorehouseProduct.count", getMapParam()));
        }
        return lazyModelStorehouseProduct;
    }

    public LazyDataModel<ProductShop> getLazyModelProductShop() throws Exception {
        if (lazyModelProductShop == null) {
            lazyModelProductShop = new LazyDataModel<ProductShop>() {

                @Override
                public List<ProductShop> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                    //return super.load(first, pageSize, sortField, sortOrder, filters); //To change body of generated methods, choose Tools | Templates.

                    List<ProductShop> lazyPS;
                    try {

                        lazyPS = productShopService.listLazy(namedQuery, getParameters(), first, pageSize);
                    } catch (Exception ex) {
                        lazyPS = new ArrayList<>();
                        //Logger.getLogger(InputProductController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return lazyPS;
                }

            };
            lazyModelProductShop.setRowCount(productShopService.count("ProductShop.count", getMapParam()));
        }

        return lazyModelProductShop;
    }

    public void obtainLazy() {
        if (searchForCode.isEmpty() && searchForName.isEmpty()) {
            namedQuery = "ProductShop.findAll";
            parameters = new HashMap<>();
            parameters.put("shopId", shop.getId());
        } else if (searchForName.isEmpty()) {
            namedQuery = "ProductShop.findCode";
            parameters = new HashMap<>();
            parameters.put("code", "%" + searchForCode + "%");
            parameters.put("shopId", shop.getId());
        } else if (searchForCode.isEmpty()) {
            namedQuery = "ProductShop.findName";
            parameters = new HashMap<>();
            parameters.put("name", "%" + searchForName + "%");
            parameters.put("shopId", shop.getId());
        } else {
            namedQuery = "ProductShop.findCodeName";
            parameters = new HashMap<>();
            parameters.put("code", "%" + searchForCode + "%");
            parameters.put("name", "%" + searchForName + "%");
            parameters.put("shopId", shop.getId());
        }
    }

    public void obtainLazyStorehouseProduct() {
        if (searchForCode.isEmpty() && searchForName.isEmpty()) {
            namedQueryStorehouseProduct = "StorehouseProduct.findAll";
            parameters = new HashMap<>();
            parameters.put("storeId", storehouse.getId());
        } else if (searchForName.isEmpty()) {
            namedQueryStorehouseProduct = "StorehouseProduct.findCode";
            parameters = new HashMap<>();
            parameters.put("code", "%" + searchForCode + "%");
            parameters.put("storeId", storehouse.getId());
        } else if (searchForCode.isEmpty()) {
            namedQueryStorehouseProduct = "StorehouseProduct.findName";
            parameters = new HashMap<>();
            parameters.put("name", "%" + searchForName + "%");
            parameters.put("storeId", storehouse.getId());
        } else {
            namedQueryStorehouseProduct = "StorehouseProduct.findCodeName";
            parameters = new HashMap<>();
            parameters.put("code", "%" + searchForCode + "%");
            parameters.put("name", "%" + searchForName + "%");
            parameters.put("storeId", storehouse.getId());
        }

    }

    public Map<String, Object> getMapParam() {
        if (mapParam == null) {
            mapParam = new HashMap<>();
            if (shop.getId() != null) {
                mapParam.put("shopId", shop.getId());
            } else {
                mapParam.put("storeId", storehouse.getId());
            }
        }
        return mapParam;
    }

    public Map<String, Object> getParameters() {
        System.out.println("shop : " + shop.getId());
        if (parameters == null) {
            parameters = new HashMap<>();
            if (shop.getId() != null) {
                parameters.put("shopId", shop.getId());
            } else {
                parameters.put("storeId", storehouse.getId());
            }

        }
        return parameters;
    }

    public void initValuesWizard() {
        mapParam = null;
        firstWizard = null;
        secondWizard = null;
        listStorehouse = null;
        listCompany = null;
        storehouse = new Storehouse();
        company = new Company();
        accountForPay = new AccountForPay();
        listShop = null;
        shop = new Shop();
        namedQueryStorehouseProduct = "StorehouseProduct.findAll";
        lazyModelProductShop = null;
        lazyModelStorehouseProduct = null;
        searchForName = "";
        searchForCode = "";
        parameters = null;
        storehouseProduct = new StorehouseProduct();
        ///////////////////////
        listProvider = null;
        /**/
        inputDocument = new InputDocument();
        inputDocument.setDetailInputDocumentList(new ArrayList<DetailInputDocument>());
        inputDocument.setEmployeeId((Employee) Faces.getSessionAttribute(FacesUtil.ATTRIBUTE_USER));
        /**/
    }

    public void updateProductShop() throws Exception {
        System.out.println("id: " + productShop.getId());
        System.out.println("id: " + productShop.getTypeMoney());
        System.out.println("id: " + productShop.getAmount());
        System.out.println("id: " + productShop.getOutputPrice());
        productShopService.update(productShop);
        FacesUtil.addMessage("Actualizado", "Se ha actualizado los datos de un producto", FacesMessage.SEVERITY_INFO);
    }

    public void updateProductStorehouse() throws Exception {
        storehouseProductService.update(storehouseProduct);
        FacesUtil.addMessage("Actualizado", "Se ha actualizado los datos de un producto", FacesMessage.SEVERITY_INFO);
    }

    public void updateListShop() throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("idCompany", company.getId());
        listShop = shopService.list("Shop.findByCompanyId", map);
    }

    public List<Storehouse> getListStorehouse() throws Exception {
        if (listStorehouse == null) {
            listStorehouse = storehouseService.list("Storehouse.findAll");
        }
        return listStorehouse;
    }

    public List<Company> getListCompany() throws Exception {
        if (listCompany == null) {
            listCompany = companyService.list("Company.findAll");
        }
        return listCompany;
    }

    public List<Shop> getListShop() {
        if (listShop == null) {
            listShop = new ArrayList<>();
        }
        return listShop;
    }

    public void setListShop(List<Shop> listShop) {
        this.listShop = listShop;
    }

    public Shop getShop() {
        return shop;
    }

    public void setShop(Shop shop) {
        this.shop = shop;
    }

    public void setListStorehouse(List<Storehouse> listStorehouse) {
        this.listStorehouse = listStorehouse;
    }

    public Storehouse getStorehouse() {
        return storehouse;
    }

    public StorehouseProduct getStorehouseProduct() {
        return storehouseProduct;
    }

    public void setStorehouseProduct(StorehouseProduct storehouseProduct) {
        this.storehouseProduct = storehouseProduct;
    }

    public void setStorehouse(Storehouse storehouse) {
        this.storehouse = storehouse;
    }

    public void setListCompany(List<Company> listCompany) {
        this.listCompany = listCompany;
    }

    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    public Integer getFirstWizard() {
        return firstWizard;
    }

    public String getSearchForName() {
        return searchForName;
    }

    public void setSearchForName(String searchForName) {
        this.searchForName = searchForName;
    }

    public String getSearchForCode() {
        return searchForCode;
    }

    public void setSearchForCode(String searchForCode) {
        this.searchForCode = searchForCode;
    }

    public void setFirstWizard(Integer firstWizard) {
        this.firstWizard = firstWizard;
    }

    public Integer getSecondWizard() {
        return secondWizard;
    }

    public void setSecondWizard(Integer secondWizard) {
        this.secondWizard = secondWizard;
    }

    public ProductShop getProductShop() {
        return productShop;
    }

    public void setProductShop(ProductShop productShop) {
        this.productShop = productShop;
    }
    /////////////////////////////////////////////////////////////////////////////
    //////////////ENTRADA DE PRODUCTOS NUEVOS ///////////////////////////////////
    @Autowired
    ProviderService providerService;
    @Autowired
    InputDocumentService inputDocumentService;
    //null
    private List<Provider> listProvider;
    private LazyDataModel<Product> lazyModelProduct;
    private Map<String, Object> paramProduct;
    private String namedQueryProduct = "Product.findAll";
    private Product product;
    private int amountProductForSale = 1;
    private double priceProductForSale = 0.0;
    //null;
    private InputDocument inputDocument = new InputDocument();

    public void initValuesSelectProduct() {
        paramProduct = null;
        lazyModelProduct = null;
        product = new Product();
        searchForCode = null;
        searchForName = null;
        amountProductForSale = 1;
        namedQueryProduct = "Product.findAll";
    }

    public boolean getExistProductInCart() {
        boolean existProduct = false;
        for (DetailInputDocument detailInputDocument : inputDocument.getDetailInputDocumentList()) {
            if (detailInputDocument.getProductId().equals(product)) {
                existProduct = true;
                //detailInputDocument.setAmount(detailInputDocument.getAmount() + amountProductForSale);
            }
        }
        return existProduct;
    }

    public void removeOfListProduct(DetailInputDocument detailInputDocument) {
        for (int i = 0; i < inputDocument.getDetailInputDocumentList().size(); i++) {
            if (inputDocument.getDetailInputDocumentList().get(i).getProductId().equals(detailInputDocument.getProductId())) {
                inputDocument.getDetailInputDocumentList().remove(i);
            }
        }
    }

    public void saveInToCart() {
        //SI NO EXISTE PRODUCTO QUE LO AGREGE AL CARRITO
        if (!getExistProductInCart()) {
            DetailInputDocument detInpDco = new DetailInputDocument();
            detInpDco.setProductId(product);
            detInpDco.setAmount(amountProductForSale);
            detInpDco.setPriceUnit(priceProductForSale);
            detInpDco.setInputDocumentId(inputDocument);

            inputDocument.getDetailInputDocumentList().add(detInpDco);
        } else {
            for (DetailInputDocument detailInputDocument : inputDocument.getDetailInputDocumentList()) {
                if (detailInputDocument.getProductId().equals(product)) {
                    detailInputDocument.setAmount(detailInputDocument.getAmount() + amountProductForSale);
                }
            }
        }

        FacesUtil.addMessage("Producto Anadido", "Se ha añadido " + amountProductForSale + " producto(s) al carrito", FacesMessage.SEVERITY_INFO);
        FacesUtil.getRequestContext().execute("modalAddToCard.hide();");
        System.out.println("Entro....");
        priceProductForSale = 0.0;
        amountProductForSale = 1;
    }

    //TIPO DE ENTRADA: AL CONTADO O CREDITO
    private Integer typeSaleDocument = 1;

    public void saveOrUpdateInputDocument() throws Exception {
        if (inputDocument.getProviderId() == null || inputDocument.getNumberDocument() == null || inputDocument.getDetailInputDocumentList().isEmpty()) {
            if (inputDocument.getProviderId() == null) {
                FacesUtil.addMessage("Falta PROVEEDOR", "Ud. Debe seleccionar un proveedor antes de continuar.", FacesMessage.SEVERITY_ERROR);
            }
            if (inputDocument.getNumberDocument() == null) {
                FacesUtil.addMessage("Falta NÚMERO DE DOCUMENTO", "Ud. Debe ingresar un número de documento antes de continuar.", FacesMessage.SEVERITY_ERROR);
            }
            if (inputDocument.getDetailInputDocumentList().isEmpty()) {
                FacesUtil.addMessage("SIN PRODUCTOS", "Debe al menos ingresar un producto para poder continuar", FacesMessage.SEVERITY_FATAL);
            }
        } else {
            if (inputDocument.getId() == null) {
                if (typeSaleDocument == 1) { //AL CONTADO
                    inputDocument.setDescription("Nueva " + inputDocument.getTypeDocument() + ""
                            + " guardada, Se ha vendido al CONTADO. y se ingreso el documento el " + (new Date()));
                    //NO GUARDA A NINGÚN LADO MAS
                } else {
                    //GUARDA A DEUDAS
                    inputDocument.setDescription("Nueva " + inputDocument.getTypeDocument() + ""
                            + " guardada, Se ha vendido al CRÉDITO. y se ingreso el documento el " + (new Date()));
                }
                // SE DEBE ACTUALIZAR LA TIENDA O EL ALMACÉN SELECCIONADO
                if (storehouse.getId() != null) {
                    for (int i = 0; i < inputDocument.getDetailInputDocumentList().size(); i++) {
                        Map<String, Object> param = new HashMap<>();
                        param.put("storeId", storehouse.getId());
                        param.put("productId", inputDocument.getDetailInputDocumentList().get(i).getProductId().getId());
                        StorehouseProduct sp = (StorehouseProduct) storehouseProductService.list("StorehouseProduct.findStoreProductId", param).get(0);
                        sp.setAmount(sp.getAmount() + inputDocument.getDetailInputDocumentList().get(i).getAmount());
                        //CAMBIAR ESTE UPDATE POR UN UPDATE CON NAMEDQUERY
                        String sql = "UPDATE StorehouseProduct sp SET sp.amount = (amount) WHERE sp.id = (id)"
                                .replace("(amount)", sp.getAmount() + "")
                                .replace("(id)", sp.getId() + "");
                        storehouseProductService.update(sql, false);
                    }
                    // ANTES DE ACTUALIZAR DEBE PREGUNTAR SI YA EXISTE EN LA BASE DE DATOS ESTOS PRODUCTOS PARA NO DUPLICAR
                    FacesUtil.addMessage("Productos Enviados", "Los productos ingresados fueron enviados hacia al almacén seleccionado", FacesMessage.SEVERITY_INFO);
                } else if (shop.getId() != null) {
                    for (int i = 0; i < inputDocument.getDetailInputDocumentList().size(); i++) {
                        Map<String, Object> param = new HashMap<>();
                        param.put("shopId", shop.getId());
                        param.put("productId", inputDocument.getDetailInputDocumentList().get(i).getProductId().getId());
                        List<ProductShop> sp = productShopService.list("ProductShop.findShopProductId", param);
                        Integer amount;
                        Integer id = null;
                        if (!sp.isEmpty()) {
                            if (sp.get(0).getAmount() != null) {
                                amount = (sp.get(0).getAmount() + inputDocument.getDetailInputDocumentList().get(i).getAmount());
                                id = sp.get(0).getId();
                                System.out.println("Guardo");
                            } else {
                                amount = (inputDocument.getDetailInputDocumentList().get(i).getAmount());
                                System.out.println("No Guardo");
                            }

                            //CAMBIAR ESTE UPDATE POR UN UPDATE CON NAMEDQUERY
                            String sql = "UPDATE ProductShop sp SET sp.amount = (amount) WHERE sp.id = (id)"
                                    .replace("(amount)", amount + "")
                                    .replace("(id)", id + "");
                            storehouseProductService.update(sql, false);
                        } else {
                            System.out.println("No encontro ningun registro");
                        }

                    }
                    // ANTES DE ACTUALIZAR DEBE PREGUNTAR SI YA EXISTE EN LA BASE DE DATOS ESTOS PRODUCTOS PARA NO DUPLICAR
                    FacesUtil.addMessage("Productos Enviados", "Los productos ingresados fueron enviados hacia al almacén seleccionado", FacesMessage.SEVERITY_INFO);
                }
                //DEBE GUARDAR CON TODAS SUS RELACIONES
                InputDocument id = inputDocumentService.save(inputDocument);
                if (typeSaleDocument == 1) {
                    // no hacer nada por que no tiene deuda
                } else if (typeSaleDocument == 2) {

                    accountForPay = new AccountForPay();
                    accountForPay.setAmount(id.getTotal());
                    accountForPay.setInputDocumentId(id);
                    accountForPay.setState(VarUtil.DEUDA);
                    accountForPay.setTypeMoney(id.getTypeMoney());
                    FacesUtil.getRequestContext().update("other");
                    FacesUtil.getRequestContext().execute("deuda.show();");
                    System.out.println(id.getTotal());
                }
                FacesUtil.addMessage("Guardado", "Se ha actualizado el Inventario con éxito", FacesMessage.SEVERITY_INFO);
                initValuesAfterSaveOrUpdate();
            } else {

            }
        }

    }

    public void saveAccountForPay() throws Exception {
        accountForPayService.save(accountForPay);
        FacesUtil.getRequestContext().update("other");
        FacesUtil.getRequestContext().execute("deuda.hide();");
        FacesUtil.addMessage("Deuda Registrada", "Se ha añadido una deuda...", FacesMessage.SEVERITY_INFO);
    }

    public void initValuesAfterSaveOrUpdate() {
        listProvider = null;
        /**/
        inputDocument = new InputDocument();
        inputDocument.setDetailInputDocumentList(new ArrayList<DetailInputDocument>());
        inputDocument.setEmployeeId((Employee) Faces.getSessionAttribute(FacesUtil.ATTRIBUTE_USER));
        typeSaleDocument = 1;

        ///////////
        lazyModelProduct = null;
        lazyModelProductShop = null;
        lazyModelStorehouseProduct = null;
    }

    public List<Provider> getListProvider() throws Exception {
        if (listProvider == null) {
            listProvider = providerService.list("Provider.findAll");
        }
        return listProvider;
    }

    public LazyDataModel<Product> getLazyModelProduct() throws Exception {
        if (lazyModelProduct == null) {
            lazyModelProduct = new LazyDataModel<Product>() {
                @Override
                public List<Product> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                    //return super.load(first, pageSize, sortField, sortOrder, filters); //To change body of generated methods, choose Tools | Templates.

                    List<Product> lazyPS;
                    try {
                        lazyPS = productShopService.listLazy(namedQueryProduct, paramProduct, first, pageSize);
                        System.out.println("Laz: " + lazyPS);
                    } catch (Exception ex) {
                        lazyPS = new ArrayList<>();
                        //Logger.getLogger(InputProductController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return lazyPS;
                }
            };
            lazyModelProduct.setRowCount(storehouseProductService.count("Product.count", null));
        }
        return lazyModelProduct;
    }

    public void calculatorTotal() {
        try {
            inputDocument.calculator();
        } catch (Exception e) {
        }

    }

    public void searchProduct() {
        paramProduct = new HashMap<>();
        if (searchForCode.isEmpty()) {
            //buscar por nombre 
            namedQueryProduct = "Product.findName";
            paramProduct.put("name", "%" + searchForName + "%");
        } else if (searchForName.isEmpty()) {
            //buscar por codigo
            namedQueryProduct = "Product.findCode";
            paramProduct.put("code", "%" + searchForCode + "%");
        } else if (!searchForCode.isEmpty() && !searchForName.isEmpty()) {
            namedQueryProduct = "Product.findNameCode";
            paramProduct.put("name", "%" + searchForName + "%");
            paramProduct.put("code", "%" + searchForCode + "%");
            //buscar por ambos
        } else {
            namedQueryProduct = "Product.findAll";
            paramProduct = null;
        }
    }

    public InputDocument getInputDocument() {
        return inputDocument;
    }

    public void setInputDocument(InputDocument inputDocument) {
        this.inputDocument = inputDocument;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public int getAmountProductForSale() {
        return amountProductForSale;
    }

    public Integer getTypeSaleDocument() {
        return typeSaleDocument;
    }

    public void setTypeSaleDocument(Integer typeSaleDocument) {
        this.typeSaleDocument = typeSaleDocument;
    }

    public void setAmountProductForSale(int amountProductForSale) {
        this.amountProductForSale = amountProductForSale;
    }

    public double getPriceProductForSale() {
        return priceProductForSale;
    }

    public void setPriceProductForSale(double priceProductForSale) {
        this.priceProductForSale = priceProductForSale;
    }

    public AccountForPay getAccountForPay() {
        return accountForPay;
    }

    public void setAccountForPay(AccountForPay accountForPay) {
        this.accountForPay = accountForPay;
    }

}
